package com.demo.swingquickticket.swing.view.ticket;

import com.demo.swingquickticket.service.TicketPanelService;
import com.demo.swingquickticket.swing.layoutUtil.GBC;
import com.demo.swingquickticket.swing.model.AppJTableModel;
import com.demo.swingquickticket.util.SpringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Data
@EqualsAndHashCode(callSuper = true)
public class TicketPanel extends JPanel {

    public static final List<String> TABLE_HEADER;
    public static final List<Class> TABLE_TYPE;

    static {
        TABLE_HEADER = Arrays.asList("", "车次", "出发站", "到达站", "出发时间", "到达时间", "历时",
                "商务座(特等座)", "一等座", "二等座", "高级软卧", "软卧一等座", "动卧",
                "硬卧二等座", "软座", "硬座", "无座", "其他");
        TABLE_TYPE = Arrays.asList(JCheckBox.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class
                , String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class);

    }

    private TicketPanelService ticketPanelService = SpringUtils.getBean("ticketPanelService");

    private JLabel from;
    private JTextField fromInput;
    private JLabel to;
    private JTextField toInput;
    private JLabel date;
    private JTextField dataInput;
    private JButton searchBtn;
    private JLabel type;
    private JCheckBox ABox;
    private JCheckBox GBox;
    private JCheckBox CBox;
    private JCheckBox DBox;
    private JCheckBox ZBox;
    private JCheckBox TBox;
    private JCheckBox KBox;
    private JCheckBox QBox;
    private Set<String> checkSet = new HashSet<>();
    private JTable ticketTable;
    private JTextArea logArea;

    public TicketPanel() {
        this.setLayout(new GridBagLayout());
        GBC gbc = GBC.getInstance().setInsets(new Insets(5, 5, 5, 5));

        setSearchBar(this, gbc);

        setTypeBar(this, gbc);

        setTableAndLog(this, gbc);

//        initLog();
    }

    private void setSearchBar(JPanel panel, GBC gbc) {
        gbc.setFill(GBC.NONE).setAnchor(GBC.CENTER).setWeightXY(10, 5).setGridWH(1,1);
        from = new JLabel("出发地:");
        panel.add(from, gbc);

        gbc.setFill(GBC.HORIZONTAL).setWeightXY(20, 5).setGridWH(2,1);
        fromInput = new JTextField();
        fromInput.setText("杭州|HZH");
        panel.add(getStationPanel(fromInput), gbc);

        gbc.setFill(GBC.NONE).setFill(GBC.CENTER).setWeightXY(10, 5).setGridWH(1,1);
        to = new JLabel("到达地:");
        panel.add(to, gbc);

        gbc.setFill(GBC.HORIZONTAL).setWeightXY(20, 5).setGridWH(2,1);
        toInput = new JTextField();
        toInput.setText("宁波|NGH");

        panel.add(getStationPanel(toInput), gbc);

        gbc.setFill(GBC.NONE).setFill(GBC.CENTER).setWeightXY(10, 5).setGridWH(1,1);
        date = new JLabel("出发日期:");
        panel.add(date, gbc);

        gbc.setFill(GBC.HORIZONTAL).setWeightXY(20, 5).setGridWH(2,1);
        dataInput = new JTextField();
        dataInput.setText("2019-06-06");
        panel.add(dataInput, gbc);

        gbc.setFill(GBC.NONE).setFill(GBC.CENTER).setWeightXY(10, 5);
        gbc.setGridWH(GridBagConstraints.REMAINDER, 1);
        searchBtn = new JButton("查询");
        searchBtn.addActionListener(e -> {
            ticketPanelService.search(ticketTable, dataInput.getText(), fromInput.getText(), toInput.getText());
            ABox.setSelected(true);
        });

        panel.add(searchBtn, gbc);
    }

    private void setTypeBar(JPanel panel, GBC gbc) {
        gbc.setFill(GBC.NONE).setFill(GBC.CENTER).setWeightXY(10, 10).setGridWH(1, 1);

        type = new JLabel("车次类型");
        panel.add(type, gbc);

        gbc.setWeightXY(10, 10).setGridWH(1, 1);
        ABox = new JCheckBox("全部(All)");
        ABox.setSelected(true);
        ABox.addItemListener(e -> {
            JCheckBox item = (JCheckBox) e.getItem();
            if (item.isSelected()) {
                GBox.setSelected(false);
                CBox.setSelected(false);
                DBox.setSelected(false);
                ZBox.setSelected(false);
                TBox.setSelected(false);
                KBox.setSelected(false);
                checkSet.clear();
                checkSet.add("All");
                System.out.println("选中了A");
                searchType();
            } else {
                checkSet.remove("All");
                if (!GBox.isSelected()) {
                    GBox.setSelected(true);
                }
                System.out.println("取消选中了A");
            }
        });
        panel.add(ABox, gbc);

        GBox = new JCheckBox("高铁(G)");
        GBox.addItemListener(e -> {
            JCheckBox item = (JCheckBox) e.getItem();
            if (item.isSelected()) {
                checkSet.add("G");
                System.out.println("选中了G");
                if (ABox.isSelected()) {
                    ABox.setSelected(false);
                }
                searchType();
            } else {
                checkSet.remove("G");
                System.out.println("取消选中了G");
                if (!typeEmpty()) {
                    searchType();
                }
            }
        });
        panel.add(GBox, gbc);

        CBox = new JCheckBox("城际(C)");
        CBox.addItemListener(e -> {
            JCheckBox item = (JCheckBox) e.getItem();
            if (item.isSelected()) {
                checkSet.add("C");
                System.out.println("选中了C");
                if (ABox.isSelected()) {
                    ABox.setSelected(false);
                }
                searchType();
            } else {
                checkSet.remove("C");
                System.out.println("取消选中了C");
                if (!typeEmpty()) {
                    searchType();
                }
            }
        });
        panel.add(CBox, gbc);

        DBox = new JCheckBox("动车(D)");
        DBox.addItemListener(e -> {
            JCheckBox item = (JCheckBox) e.getItem();
            if (item.isSelected()) {
                checkSet.add("D");
                System.out.println("选中了D");
                if (ABox.isSelected()) {
                    ABox.setSelected(false);
                }
                searchType();
            } else {
                checkSet.remove("D");
                System.out.println("取消选中了D");
                if (!typeEmpty()) {
                    searchType();
                }
            }
        });
        panel.add(DBox, gbc);

        ZBox = new JCheckBox("直达(Z)");
        ZBox.addItemListener(e -> {
            JCheckBox item = (JCheckBox) e.getItem();
            if (item.isSelected()) {
                checkSet.add("Z");
                System.out.println("选中了Z");
                if (ABox.isSelected()) {
                    ABox.setSelected(false);
                }
                searchType();
            } else {
                checkSet.remove("Z");
                System.out.println("取消选中了Z");
                if (!typeEmpty()) {
                    searchType();
                }
            }
        });
        panel.add(ZBox, gbc);

        TBox = new JCheckBox("特快(T)");
        TBox.addItemListener(e -> {
            JCheckBox item = (JCheckBox) e.getItem();
            if (item.isSelected()) {
                checkSet.add("T");
                System.out.println("选中了T");
                if (ABox.isSelected()) {
                    ABox.setSelected(false);
                }
                searchType();
            } else {
                checkSet.remove("T");
                System.out.println("取消选中了T");
                if (!typeEmpty()) {
                    searchType();
                }
            }
        });
        panel.add(TBox, gbc);

        KBox = new JCheckBox("快速(K)");
        KBox.addItemListener(e -> {
            JCheckBox item = (JCheckBox) e.getItem();
            if (item.isSelected()) {
                checkSet.add("K");
                System.out.println("选中了K");
                if (ABox.isSelected()) {
                    ABox.setSelected(false);
                }
                searchType();
            } else {
                checkSet.remove("K");
                System.out.println("取消选中了K");
                if (!typeEmpty()) {
                    searchType();
                }
            }
        });
        panel.add(KBox, gbc);

        gbc.setGridWH(GridBagConstraints.REMAINDER, 1);
        QBox = new JCheckBox("其他(other暂无)");
        QBox.setEnabled(false);
        panel.add(QBox, gbc);
    }

    private void setTableAndLog(JPanel panel, GBC gbc) {
        AppJTableModel tableModel = new AppJTableModel();
        tableModel.setHeader(TABLE_HEADER);
        ticketTable = new JTable(tableModel);

        JScrollPane ticketJScrollPane = new JScrollPane(ticketTable);
        gbc.setFill(GBC.BOTH).setWeightXY(100, 60).setGridWH(GridBagConstraints.REMAINDER, 6);
        panel.add(ticketJScrollPane, gbc);

        gbc.setFill(GBC.HORIZONTAL).setWeightXY(100, 5).setGridWH(GridBagConstraints.REMAINDER, 1);
        JButton startBtn = new JButton("抢票");
        startBtn.addActionListener(e -> {
            AppJTableModel model = (AppJTableModel) ticketTable.getModel();
            List<String> selectedStationCode = model.getSelectedStationCode();
            if (selectedStationCode.isEmpty()) {
                JOptionPane.showMessageDialog(this, "未选中车次");
                return;
            }
            new TicketConfirmDialog(new JFrame(), selectedStationCode, model.getStartDate(), model.getFromStation(), model.getToStation());
        });
        panel.add(startBtn, gbc);

        logArea = new JTextArea();
        logArea.setFont(new Font(null,Font.BOLD,20));
        logArea.setEnabled(false);
        logArea.setWrapStyleWord(true);
        logArea.setLineWrap(true);
        JScrollPane logAreaJScrollPane = new JScrollPane(logArea);
        gbc.setFill(GBC.BOTH).setWeightXY(100, 20).setGridWH(GridBagConstraints.REMAINDER, 2);
        panel.add(logAreaJScrollPane, gbc);
    }

    private JPanel getStationPanel(JTextField field) {
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new BorderLayout());
        field.setEnabled(false);
        final JTextField finalField = field;
        JButton stationButton = new JButton("查询");
        stationButton.addActionListener(e -> {
            StationDialog stationDialog = StationDialog.getInstance();
            finalField.setText(stationDialog.getResult());
        });
        jPanel.add(field, BorderLayout.CENTER);
        jPanel.add(stationButton, BorderLayout.EAST);
        return jPanel;
    }

    private void initLog() {

        ThreadPoolTaskExecutor threadPoolTaskExecutor = SpringUtils.getBean("myExecutor");

        OutputStream outputStream = new OutputStream() {
            @Override
            public void write(byte[] buffer, int offset, int length) throws IOException
            {
                final String text = new String (buffer, offset, length);
                threadPoolTaskExecutor.execute(() -> logArea.append (text));
            }
            @Override
            public void write(int b) throws IOException
            {
                write (new byte [] {(byte)b}, 0, 1);
            }
        };

        PrintStream printStream = new PrintStream(outputStream);

        System.setOut(printStream);
        System.setErr(printStream);
    }

    private boolean typeEmpty() {
        if (!GBox.isSelected() && !CBox.isSelected() && !DBox.isSelected() && !ZBox.isSelected() && !TBox.isSelected() && !KBox.isSelected()) {
            ABox.setSelected(true);
            return true;
        }
        return false;
    }

    private void searchType() {
        AppJTableModel model = (AppJTableModel) ticketTable.getModel();
        model.setSearchData(checkSet);
        ticketTable.updateUI();
    }
}
